home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 7
/
Apprentice-Release7.iso
/
Environments
/
Small Eiffel 0.4.8
/
lib_std
/
bit_n.e
< prev
next >
Wrap
Text File
|
1997-04-13
|
7KB
|
295 lines
-- Part of SmallEiffel -- Read DISCLAIMER file -- Copyright (C)
-- Dominique COLNET and Suzanne COLLIN -- colnet@loria.fr
--
expanded class BIT_N
--
-- Indexed Bit sequences of length `N'. This class is a template,
-- not a real class; to obtain a meaningful class, replace `N'
-- with a positive integer throughout.
--
-- An INTEGER index can be used to access each bit of the sequence.
-- The leftmost bit has index 1 and the rightmost bit has index `N'.
--
-- Note 1 : corresponding C mapping depends on actual `N' and is
-- PLATFORM dependant (see class PLATFORM).
-- When `N' is in range [0 .. Character_bits], C type
-- is a simple "unsigned char".
-- When `N' is in range [Character_bits+1 .. Integer_bits],
-- C type is "unsigned".
-- When `N' is greater than Integer_bits, C type is C array
-- of "unsigned" of the form :
-- "unsigned storage[`N' div Integer_bits]"
-- The array is obviously big enough to fit with `N'. As
-- for previous mapping, the left most bit (at index 1 in
-- Eiffel) is always the left most in C memory.
--
-- Note 2 : Eiffel BIT code is portable. Generated C code for class
-- BIT may not be portable (because sizeof(int) may change).
-- To produce a portable C code, you can compile your Eiffel
-- code using a machine with very small sizeof(int). Also note
-- that doing this may run a little bit slowly.
--
inherit
BIT_N_REF
redefine print_on, fill_tagged_out_memory
end;
feature {NONE}
storage: POINTER;
-- The beginning of the storage zone (first byte
-- contains the beginning of the sequence).
feature -- Basic Accessing :
count: INTEGER is
-- Number of bits in the sequence (the value of `N').
external "CSE"
end;
item(idx: INTEGER): BOOLEAN is
-- True if i-th bit is 1, false otherwise.
require
inside_bounds: 1 <= idx and then idx <= count
external "CSE"
end;
put(value: BOOLEAN; idx: INTEGER) is
-- Set bit `idx' to 1 if value is true, 0 otherwise.
require
inside_bounds: 1 <= idx and idx <= count
external "CSE"
ensure
value = item(idx)
end;
put_1(idx: INTEGER) is
-- Set bit `idx' to 1.
require
inside_bounds: 1 <= idx and idx <= count
external "CSE"
ensure
item(idx)
end;
put_0(idx: INTEGER) is
-- Set bit `idx' to 0.
require
inside_bounds: 1 <= idx and idx <= count
external "CSE"
ensure
not item(idx)
end;
feature -- Rotating and shifting :
infix "^" (s: INTEGER): like Current is
-- Sequence shifted by `s' positions (positive `s' shifts
-- right, negative left; bits falling off the sequence's
-- bounds are lost).
-- See also infix "@>>" and infix "@<<".
require
s.abs<count;
do
if s >= 0 then
Result := Current @>> s;
else
Result := Current @<< -s;
end;
end;
infix "@>>" (s: INTEGER): like Current is
-- Sequence shifted right by `s' positions.
-- Same as infix "^" when `s' is positive (may run a little
-- bit faster).
require
s > 0
external "CSE"
end;
infix "@<<" (s: INTEGER): like Current is
-- Sequence shifted left by `s' positions.
-- Same as infix "^" when `s' is negative (may run a little
-- bit faster.
require
s > 0
external "CSE"
end;
infix "#" (s: INTEGER): like Current is
-- Sequence rotated by `s' positions (positive right,
-- negative left).
require
s.abs<count;
do
if s >= 0 then
Result := Current #>> s;
else
Result := Current #>> -s;
end;
end
infix "#>>" (s: INTEGER): like Current is
-- Sequence rotated by `s' positions right.
require
s >= 0;
s < count
local
i: INTEGER;
bit: BOOLEAN;
do
from
i := s;
Result := Current;
until
i = 0
loop
bit := Result.item(count);
Result := Result @>> 1;
Result.put(bit,1);
i := i - 1;
end;
end;
infix "#<<" (s: INTEGER): like Current is
-- Sequence rotated by `s' positions left.
require
s >= 0;
s < count
local
i: INTEGER;
bit: BOOLEAN;
do
from
i := s;
Result := Current;
until
i = 0
loop
bit := Result.item(1);
Result := Result @<< 1;
Result.put(bit,count);
i := i - 1;
end;
end;
feature -- Bitwise Logical Operators :
infix "and" (other: like Current): like Current is
-- Bitwise `and' of Current with `other'
external "CSE"
end;
infix "implies" (other: like Current): like Current is
-- Bitwise implication of Current with `other'
do
Result := not (Current or other);
end;
prefix "not": like Current is
-- Bitwise `not' of Current.
external "CSE"
end;
infix "or" (other: like Current): like Current is
-- Bitwise `or' of Current with `other'
external "CSE"
end;
infix "xor" (other : like Current) : like Current is
-- Bitwise `xor' of Current with `other'
external "CSE"
end;
feature -- Conversions :
to_string: STRING is
-- String representation of bit sequence.
-- A zero bit is mapped to '0', a one bit to '1'.
-- Leftmost bit is at index 1 in the returned string.
--
-- Note: see `append_in' to save memory.
do
tmp_string.clear;
append_in(tmp_string);
Result := tmp_string.twin;
ensure then
Result.count = count
end;
to_integer: INTEGER is
require
count <= Integer_bits
do
c_inline_c("R=C;");
end;
to_character: CHARACTER is
require
count <= Character_bits
do
c_inline_c("R=C;");
end;
feature -- Others :
all_cleared: BOOLEAN is
-- Are all bits set to 0 ?
local
i: INTEGER;
do
from
Result := true;
i := count;
until
not Result or else i = 0
loop
Result := not item(i);
i := i - 1;
end;
end;
feature -- Printing :
append_in(str: STRING) is
local
i: INTEGER;
do
from
i := 1;
until
i > count
loop
if item(i) then
str.extend('1');
else
str.extend('0');
end;
i := i + 1;
end;
end;
print_on(file: STD_FILE_WRITE) is
do
tagged_out_memory.clear;
Current.append_in(tagged_out_memory);
tagged_out_memory.extend('B');
file.put_string(tagged_out_memory);
end;
fill_tagged_out_memory is
do
Current.append_in(tagged_out_memory);
tagged_out_memory.extend('B');
end;
feature {NONE}
tmp_string: STRING is
once
!!Result.make(128);
end;
end -- BIT_N